home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Assemblers / hecasm / lex.c < prev    next >
C/C++ Source or Header  |  1995-07-26  |  9KB  |  439 lines

  1.  
  2. #include "asm.h"
  3. #include "global.h"
  4.  
  5. vtype token;            /* token parsed from expression */
  6. vtype opq[SRCMAX];        /* queue of tokens */
  7. int optop;            /* head pointer for the queue */
  8. int undefined;            /* true when an expression contained an */
  9.                 /* undefined symbol */
  10.  
  11. /* evaluate an expression and take care of all the flags and stuff to */
  12. /* assign it to a symbol. This is called for statements like "a = b + 1" */
  13. /* sp is a pointer to the symbol in the ust where the information */
  14. /* is to be stored */
  15. evaluate(sp)
  16. struct sym *sp;
  17. {
  18.  
  19. /* no undefined symbols in the expression yet */
  20. undefined = FALSE;
  21.  
  22. /* initialize the queue */
  23. optop = 0;
  24.  
  25. /* create a postfix image of the expression in opq */
  26. eval();
  27.  
  28. /* evaluate the image */
  29. sp->s_value = post();
  30.  
  31. /* some symbol was undefined making this symbol undefined */
  32. if (undefined)
  33.     sp->s_type |= S_ABS;
  34. else
  35.     if (pass)
  36.     /* on the first pass make it just defined */
  37.         sp->s_type |= S_DEF;
  38.     else
  39.     /* on the second pass make it valid */
  40.         sp->s_type |= S_VALID;
  41. }
  42.  
  43.  
  44. /* evaluate an expression and return the result */
  45. expr()
  46. {
  47. int val;
  48.  
  49. /* initialize the front of the queue */
  50. optop = 0;
  51.  
  52. /* create a tokenized postfix image of the expression */
  53. eval();
  54.  
  55. /* evaluate it */
  56. val = post();
  57. return(val);
  58. }
  59.  
  60.  
  61. /* this function gets the next symbol or value in the source buffer */
  62. /* tokenizes it an returns it */
  63. lexan()
  64. {
  65. char id[NCPS];
  66. int t;
  67. struct sym *p;
  68.  
  69. /* get a character */
  70. t = getnb();
  71.  
  72. /* the next object must be a number */
  73. if (isdigit(t))
  74.     {
  75.     /* get the string of digits evaluate it an enter it as a token */
  76.     getid(t,id);
  77.     token.uval.ival = numconv(id);
  78.     token.type = NUM;
  79.     return(NUM);
  80.     }
  81. else if (alpha(t))
  82.     {
  83.     /* it must be a symbol */
  84.     getid(t,id);
  85.  
  86.     /* give it a pointer to its record in the ust */
  87.     token.uval.sval = ustlookup(id);
  88.     token.type = ID;
  89.     return(ID);
  90.     }
  91. else if (t == '\'')
  92.     {
  93.     /* it must be a character constant */
  94.     token.uval.ival = getmap();
  95.     token.type = NUM;
  96.     if (getnb() != '\'')
  97.         err('h',"illegal character constant");
  98.     return(NUM);
  99.     }
  100. else if (t == '\0')
  101.     {
  102.     /* end of line */
  103.     return(DONE);
  104.     }
  105. else
  106.     {
  107.     /* must be an operator */
  108.     return(validop(t));
  109.     }
  110. }
  111.  
  112.         
  113. /* use lexan & emit to tokenize an expression and put it in opq */
  114. eval()
  115. {
  116. int tos;
  117. optype stack[STSIZE], c;
  118.  
  119. /* reset the operator - operand stack */
  120. tos = 0;
  121.  
  122. /* evaluate the expression */
  123. while((c.val = lexan()) != DONE && c.val != NONE)
  124.     {
  125.     /* term gets an arithmetic term this might be "1" or "symbol" */
  126.     /* or "-1" or "!symbol" etc.  It also gets the next token */
  127.     /* from the source text */
  128.     if ((c.val = term(c.val)) == DONE || c.val == NONE)
  129.         {
  130.         /* almost done, perform everything on the stack */
  131.         while(tos != 0)
  132.             emit(stack[tos--].val);
  133.         return;
  134.         }
  135.  
  136.     /* get the precedence of the operator */
  137.     c.pr = preced(c.val);
  138.         
  139.     /* keep operators on the stack in ascending precedence to assure */
  140.     /* correct association */
  141.     if((c.pr > stack[tos].pr) || (tos == 0))
  142.         {
  143.         /* push the operator */
  144.         stack[++tos] = c;
  145.  
  146.         /* do the next operator */
  147.         continue;
  148.         }
  149.        
  150.     /* start evaluating into the stack until something of lower */
  151.     /* precedence than the one in temporary storage is found */
  152.     for(;;)
  153.         {
  154.         emit(stack[tos--]);
  155.    
  156.         /* if the stack is empty stop */
  157.         if(tos == 0)
  158.             break;
  159.         
  160.         /* the precedence of the operation on top of the stack is */
  161.         /* high enough then shift things around and keep going */
  162.         if (c.pr > stack[tos].pr) 
  163.         break;
  164.         }
  165.     stack[++tos] = c;
  166.     }
  167.  
  168. err('M',"missing operand");
  169. return(c.val);
  170. }
  171.  
  172.  
  173. /* get a term as described above */
  174. term(tok)
  175. int tok;
  176. {
  177. int nc;
  178.  
  179. /* act on the token passed here */
  180. switch(tok)
  181.     {
  182.     /* open parenthesies */
  183.     /* a parenthesized expression is treated as a single term therefore */
  184.     /* eval is called recursively */
  185.     case OP:
  186.         if (eval() == NONE)
  187.             {
  188.             if ((tok = getnb()) != ')')
  189.                 {
  190.                 err(')',"missing right parentheses");
  191.                 putback(tok);
  192.                 }
  193.             }
  194.         else
  195.             err(')',"missing right parentheses");
  196.         break;
  197.  
  198.     /* negative sign */
  199.     case MI:
  200.         term(lexan());
  201.         emit(NE);
  202.         break;
  203.  
  204.     /* complement '~' */
  205.     case CO:
  206.         term(lexan());
  207.         emit(CO);
  208.         break;
  209.  
  210.     /* negate '!' */
  211.     case NG:
  212.         term(lexan());
  213.         emit(NG);
  214.         break;
  215.  
  216.     /* a number */
  217.     case NUM:
  218.         emit(NUM);
  219.         break;
  220.  
  221.     /* a symbol */
  222.     case ID:
  223.         emit(ID);
  224.         break;
  225.  
  226.     /* this one is wrong so try another */
  227.     default:
  228.         err('t',"missing expression term");
  229.         term(lexan());
  230.     }
  231.  
  232. /* get the next token */
  233. nc = lexan();
  234. if (nc == OP)
  235.     {
  236.     /* this would make an invalid expression */
  237.     putback('(');
  238.     nc = DONE;
  239.     }
  240. return(nc);
  241. }
  242.  
  243.  
  244.  
  245. /* convert a number represented as a string in decimal, hexadecimal, octal */
  246. /* or binary form to an integer */
  247. numconv(str)
  248. char *str;
  249. {
  250. int res;
  251.  
  252. /* the second character tells the base */
  253. /* hex - 0x00 */
  254. /* oct - 0o00 */
  255. /* bin - 0b00 */
  256. /* dec - 0d00 or 00 */
  257.  
  258. switch(*(str+1))
  259.     {
  260.     /* hex */
  261.     case 'x':
  262.         {
  263.     /* leading 0 */
  264.     if (*str != '0')
  265.         {
  266.         err('H',"improper hex format");
  267.         return(0);
  268.         }
  269.         else
  270.         /* get the value */
  271.             if (!sscanf((str+2),"%x",&res))
  272.                 err('H',"improper hex format");
  273.         return(res);
  274.         }
  275.     case 'o':
  276.         {
  277.     /* leading 0 */
  278.     if (*str != '0')
  279.         {
  280.         err('O',"improper octal format");
  281.         return(0);
  282.             }
  283.         else
  284.         /* get the value */
  285.             if (!sscanf((str+2),"%o",&res))
  286.             err('O',"improper octal format");
  287.         return(res);
  288.         }
  289.     case 'b':
  290.         {
  291.     /* leading 0 */
  292.     if (*str != '0')
  293.         {
  294.         err('B',"improper binary format");
  295.         return(0);
  296.             }
  297.         else
  298.         /* get the value */
  299.         {
  300.             res = 0;
  301.         str++;
  302.             
  303.         /* shift on every charater and add one when the char is '1' */
  304.         while (*++str != '\0')
  305.                 {
  306.             res = res << 1;
  307.             if (*str == '1')
  308.                 res++;
  309.                 else
  310.                 /* not a zero or a one */
  311.             if (*str != '0')
  312.                     {
  313.                 err('B',"improper binary format");
  314.                 return(0);
  315.                 }
  316.             }
  317.         }
  318.     return(res);
  319.     }
  320.     case 'd' :
  321.         {
  322.     /* leading 0 */
  323.     if (*str != '0')
  324.         {
  325.         err('D',"improper decimal format");
  326.         return(0);
  327.             }
  328.         else
  329.         /* get the value */
  330.             if (!sscanf((str+2),"%d",&res))
  331.             err('D',"improper decimal format");
  332.         return(res);
  333.         }
  334.     }
  335.  
  336. /* if the base was not explicitly specified then evaluate according */
  337. /* to the default */
  338. switch (radix)
  339.     {
  340.     case OCT:
  341.         /* get the value */
  342.         if(!sscanf(str,"%o",&res))
  343.             err('O',"improper octal format");
  344.         return(res);
  345.     case DEC:
  346.         if(!sscanf(str,"%d",&res))
  347.             err('D',"improper decimal format");
  348.         return(res);
  349.     case HEX:
  350.         if(!sscanf(str,"%x",&res))
  351.             err('H',"improper hex format");
  352.         return(res);
  353.     case BIN:
  354.         /* get the value */
  355.         res = 0;
  356.             
  357.         /* shift on every charater and add one when the char is '1' */
  358.         while (*str != '\0')
  359.             {
  360.             res = res << 1;
  361.             if (*str == '1')
  362.                 res++;
  363.             else
  364.                 /* not a zero or a one */
  365.                 if (*str != '0')
  366.                 {
  367.                 err('B',"improper binary format");
  368.                 return(0);
  369.                     }
  370.         str++;
  371.         }
  372.         return(res);
  373.     }
  374. }
  375.  
  376.  
  377. /* return the precedence of an operator */
  378. preced(c)
  379. int c;
  380. {
  381.  
  382. switch(c)
  383.     {
  384.     case PL:
  385.     case MI:
  386.         return(12);
  387.     case MU:
  388.     case DI:
  389.     case MO:
  390.         return(13);
  391.     case AN:
  392.         return(8);
  393.     case OR:
  394.         return(6);
  395.     case XO:
  396.         return(7);
  397.     default:
  398.         err('p',"missing operator");
  399.         return(NONE);
  400.     }
  401. }
  402.  
  403.  
  404. /* return the token for an operator */
  405. validop(c)
  406. int c;
  407. {
  408.  
  409. switch (c)
  410.     {
  411.     case '+':
  412.         return(PL);
  413.     case '-':
  414.         return(MI);
  415.     case '*':
  416.         return(MU);
  417.     case '/':
  418.         return(DI);
  419.     case '%':
  420.         return(MO);
  421.     case '&':
  422.         return(AN);
  423.     case '|':
  424.         return(OR);
  425.     case '^':
  426.         return(XO);
  427.     case '(':
  428.         return(OP);
  429.     case '~':
  430.         return(CO);
  431.     case '!':
  432.         return(NG);
  433.     default:
  434.         putback(c);
  435.         return(NONE);
  436.     }
  437. }
  438.  
  439.